/******************************************************************************
 * @brief    软件定时器<依赖于b_list模块>
 ******************************************************************************/
#include "app_timer.h"

LIST(timer_list);

static uint32_t sys_timer_now = 0;

uint32_t b_get_sys_timer(void)
{
    return sys_timer_now;
}

void timer_update(void)
{
	b_timer_id_t item = NULL;
	uint32_t cur_sys_timer = sys_timer_now;
	
	cur_sys_timer++;
	for(item = (b_timer_id_t)list_head(timer_list); item != NULL ; item = list_item_next(item))
	{
		if(item->active){
			if(cur_sys_timer == item->end_val){
				if(item->repeat_period){
					item->end_val = cur_sys_timer + item->repeat_period;
				}else{
					item->active = 0;
				}
				item->handler();
			}
		}
	}
	sys_timer_now = cur_sys_timer;
}

uint8_t b_timer_create(b_timer_id_t const * p_timer,
                            b_timer_mode_t mode,
                            b_timerout_handler_t timeout_handler)
{
	if (p_timer == NULL || timeout_handler == NULL)
	{
			return 1;
	}
		
	b_timer_id_t p_t = (b_timer_id_t) *p_timer;
	p_t->handler = timeout_handler;
	p_t->repeat_period = (mode == B_TIMER_MODE_REPEATED) ? 1 : 0;
	p_t->active = 0;
    list_add(timer_list,p_t);
	return 0;
}


uint8_t b_timer_delete(b_timer_id_t const * p_timer)
{
	b_timer_id_t p_t = (b_timer_id_t) *p_timer;
	p_t->active = 0;
	list_remove(timer_list,p_t);
	return 0;
}


uint8_t b_timer_start(b_timer_id_t const * p_timer, uint32_t timeout_ticks)
{
	b_timer_id_t p_t = (b_timer_id_t) *p_timer;

	if (p_t->active)
	{
			return 0;
	}

	p_t->end_val = b_get_sys_timer() + timeout_ticks;

	if (p_t->repeat_period)
	{
			p_t->repeat_period = timeout_ticks;
	}

	p_t->active = 1;
    
	return 0;
}	

uint8_t b_timer_stop(b_timer_id_t const *p_timer)
{
	b_timer_id_t p_t = (b_timer_id_t) *p_timer;
	p_t->active = 0;
	return 0;
}	

uint8_t b_timer_reload(b_timer_id_t const * p_timer, uint32_t timeout_ticks)
{
	b_timer_id_t p_t = (b_timer_id_t) *p_timer;

	if (!p_t->active)
	{
		return 0;
	}

	p_t->end_val = b_get_sys_timer() + timeout_ticks;

	if (p_t->repeat_period)
	{
		p_t->repeat_period = timeout_ticks;
	}
	return 0;
}

#ifdef TIMER_MEASURE_MAX
static uint32_t _timer_measure_buf[TIMER_MEASURE_MAX];
static uint32_t _timer_measure_start = 0;
void b_measure_start(void)
{
	uint8_t i;
	for(i=0;i<TIMER_MEASURE_MAX;i++){
		_timer_measure_buf[i] = 0;
	}
	_timer_measure_start = b_get_sys_timer();
}

uint8_t b_measure_stop(uint8_t id)
{
	if(id >= TIMER_MEASURE_MAX) return 1;

	if(b_get_sys_timer() >= _timer_measure_start){
		_timer_measure_buf[id] = b_get_sys_timer() - _timer_measure_start;
	}else{
		_timer_measure_buf[id] = TIMER_TICKCNT_MAX - _timer_measure_start + b_get_sys_timer();
	}	
	return 0;
}

uint32_t b_measure_get(uint8_t id)
{
	if(id >= TIMER_MEASURE_MAX) return 0;
	return _timer_measure_buf[id];
}
#endif
